#pragma once
#include<iostream>
#include<string>
#include<unordered_map>
#include<cassert>
#include<fstream>
#include<vector>
#include"../Common/log.hpp"
#include"../Common/util.hpp"

namespace ns_model
{
    using namespace ns_log;
    using namespace ns_util;
    //MVC结构。M获取数据信息
    struct Question
    {
        std::string _number;//题目编号
        std::string _title;//题目标题
        std::string _level;//题目难度
        int _cpu_limit;//题目cpu限制
        int _mem_limit;//题目内存限制

        std::string _desc;//文件描述
        std::string _header;//预设代码
        std::string _tail;//测试代码
    };
    static std::string QuestionPath = "./questions/";
    class Model
    {
    public:
        Model()
        {
            assert(LoadAllQuestionsList(QuestionPath));
        }
        ~Model()
        {}
        //开始加载题库,载入文件题库路径
        bool LoadAllQuestionsList(const std::string path)
        {
            std::string list_path = path + "/question.list";
            std::ifstream in(list_path);
            if(!in.is_open())
            {
                LOG(FATAL)<<"未成功加载题库路径"<<"\n";
                return false;
            }

            std::string line;
            while(getline(in,line))
            {
                if(line[0] == '#')
                {
                    continue;
                }
                std::vector<std::string> target;
                StringUtil::SplitString(line,&target," ");
                if(target.size()!=5)
                {
                    LOG(WARNING)<<line[0]<<"编号文件配置存在错误"<<"\n";
                    continue;
                }
                Question q;
                q._number = target[0];
                q._title = target[1];
                q._level = target[2];
                q._cpu_limit = atoi(target[3].c_str());
                q._mem_limit = atoi(target[4].c_str());

                std::string question_path = path;
                question_path += q._number;
                question_path += "/";

                FileUtil::ReadFile(question_path+"header.cpp",&(q._header),true);
                FileUtil::ReadFile(question_path+"desc.txt",&(q._desc),true);
                FileUtil::ReadFile(question_path+"tail.cpp",&(q._tail),true);
                
                _map[target[0]] = q;
            }
            in.close();
            LOG(INFO)<<"题库录入成功!"<<"\n";
            return true;
        }
        //获取当前题目列表信息
        bool GetAllQestions(std::vector<Question>* v)
        {
            if(_map.empty())
            {
                LOG(ERROR) << "当前用户获取题目信息失败，内存中不存在题目信息记录" << "\n";
                return false;
            }
            for(auto& obj:_map)
            {
                v->push_back(obj.second);
            }
            return true;
        }
        //获取指定编号题目
        bool GetOneQuestion(const std::string number,Question* q)
        {
            auto it = _map.find(number);
            if(it == _map.end())
            {
                LOG(ERROR) << "当前用户获取题目信息失败，内存中不存在此题目信息记录" << "\n";
                return false;
            }
            *q = it->second;
            return true;
        }
    private:
        std::unordered_map<std::string,Question>_map;
    };
}